/**
 * 
 */
package com.cn.practice.visitor;

import java.util.ArrayList;
import java.util.List;

/**
 * 访问着模式 通常使用在数据结构变化不大 但是业务功能变化大的系统
 * 比如报表 ui 统计图都可以设计为访问者模式
 * @author zhangyang
 *
 */
public class VisitorPractice {
public static void main(String[] args) {
	/**
	 * 实现需求 男人女人共同为选手评判 评判有成功和失败两种
	 * 核心 双分派
	 */
	VisitorObject visitorObject = new VisitorObject();
	visitorObject.attach(new Man());
	visitorObject.attach(new Woman());
	visitorObject.check(new SuccessAction());
	//继续评价 不需要在动人了 只需要修改评价工作就可以了
	visitorObject.check(new FailAction());
}
}

/**
 * 访问接口
 * @author zhangyang
 *
 */
interface Action{
	void getManResult(Man man);
	void getWomanResult(Woman woman);
}

class SuccessAction implements Action{

	@Override
	public void getManResult(Man man) {
		// TODO Auto-generated method stub
		System.out.println("男人评价成功");
	}

	@Override
	public void getWomanResult(Woman woman) {
		// TODO Auto-generated method stub
		System.out.println("女人评价成功");
	}
	
}

class FailAction implements Action{

	@Override
	public void getManResult(Man man) {
		// TODO Auto-generated method stub
		System.out.println("男人评价为失败");
	}

	/* (non-Javadoc)
	 * @see com.cn.practice.visitor.Action#getWomanResult(com.cn.practice.visitor.Woman)
	 */
	@Override
	public void getWomanResult(Woman woman) {
		// TODO Auto-generated method stub
		System.out.println("女人评价为失败");
	}
	
}

/**
 * 抽象访问对象-聚合访问接口
 * @author zhangyang
 *
 */
abstract class Person{
	abstract void accept(Action action);
}

class Man extends Person{

	@Override
	void accept(Action action) {
		// TODO Auto-generated method stub
		action.getManResult(this);
	}
	
}

class Woman extends Person{

	@Override
	void accept(Action action) {
		// TODO Auto-generated method stub
		action.getWomanResult(this);
	}
	
}

/**
 * 访问模式构造器 里面聚合了多个抽象访问对象
 * @author zhangyang
 *
 */
class VisitorObject{
	List<Person> persons=new ArrayList<Person>();
	//添加访问者
	public void attach(Person person) {
		persons.add(person);
	}
	//移除访问者
	public void remove(Person person) {
		persons.remove(person);
	}
	//开始评价
	public void check(Action action) {
		for(Person person:persons) {
			person.accept(action);
		}
	}
}